from errors import Duplicate, Missing
from model.user import User

from data.init import IntegrityError, curs

curs.execute(
    """
    CREATE TABLE IF NOT EXISTS
    user (
        name TEXT PRIMARY KEY,
        hash TEXT
    )
    """
)
# Table for "deleted" users
curs.execute(
    """
    CREATE TABLE IF NOT EXISTS
    xuser (
        name TEXT PRIMARY KEY,
        hash TEXT
    )
    """
)


def _row_to_model(row: tuple) -> User:
    name, hash = row
    return User(name=name, hash=hash)


def _model_to_dict(user: User) -> dict:
    return user.model_dump()


def get_one(name: str) -> User:
    query = "SELECT * FROM user WHERE name = :name"
    curs.execute(query, {"name": name})
    if row := curs.fetchone():
        return _row_to_model(row)
    raise Missing(msg=f"User '{name}' not found")


def create(user: User, table: str = "user") -> User:
    """Create `user` in user or xuser table"""
    query = f"""
    INSERT INTO {table} (name, hash)
    VALUES (:name, :hash)
    """
    try:
        curs.execute(query, _model_to_dict(user))
    except IntegrityError as ex:
        raise Duplicate(msg=f"User '{user.name}' already exists in '{table}'") from ex

    if table == "user":
        return get_one(user.name)
    return user


def modify(name: str, user: User) -> User:
    query = "UPDATE user SET name = :name, hash = :hash WHERE name = :orig_name"
    params = {"name": user.name, "hash": user.hash, "orig_name": name}
    curs.execute(query, params)

    if curs.rowcount == 1:
        return get_one(user.name)
    raise Missing(msg=f"User '{name}' not found")


def delete(name: str) -> None:
    """Move user with `name` from user to xuser table"""
    user = get_one(name)
    query = "DELETE FROM user WHERE name = :name"
    curs.execute(query, {"name": name})

    if curs.rowcount != 1:
        raise Missing(msg=f"User '{name}' not found")
    create(user, table="xuser")
    return None
